package com.cheer.dao;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cheer.dto.LimitedDurationDTO;
import com.cheer.dto.MallOrderQueryDTO;
import com.cheer.entity.MallOrderEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cheer.enums.MallOrderStatusEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 订单表
 *
 * @author cheer
 */
@Mapper
@Repository
public interface MallOrderDao extends BaseMapper<MallOrderEntity> {

    default IPage<MallOrderEntity> selectPageByQueryCondition(MallOrderQueryDTO orderQueryDTO) {
        QueryWrapper<MallOrderEntity> queryWrapper = new QueryWrapper<>();

        if (orderQueryDTO.getShopId() != null) {
            queryWrapper.eq("shop_id", orderQueryDTO.getShopId());
        }

        String orderNumber = StringUtils.trimToNull(orderQueryDTO.getOrderNumber());
        if (orderNumber != null) {
            queryWrapper.like("number", orderNumber);
        }

        Date fromDate = orderQueryDTO.getFromDate();
        if (fromDate != null) {
            queryWrapper.ge("create_time", fromDate);
        }

        Date toDate = orderQueryDTO.getToDate();
        if (toDate != null) {
            queryWrapper.lt("create_time", DateUtils.addDays(toDate, 1));
        }

        if (orderQueryDTO.getStatus() != null) {
            queryWrapper.eq("status", orderQueryDTO.getStatus());
        }

        if (orderQueryDTO.getRefundStatus() != null) {
            queryWrapper.eq("refund_status", orderQueryDTO.getRefundStatus());
        }

        Date hexiaoFromDate = orderQueryDTO.getHexiaoFromDate();
        if (hexiaoFromDate != null) {
            queryWrapper.ge("hexiao_time", hexiaoFromDate);
        }

        Date hexiaoToDate = orderQueryDTO.getHexiaoToDate();
        if (hexiaoToDate != null) {
            queryWrapper.lt("hexiao_time", DateUtils.addDays(hexiaoToDate, 1));
        }

        queryWrapper.eq("type", orderQueryDTO.getType());

        return selectPage(new Page<>(orderQueryDTO.getPageNum(), orderQueryDTO.getPageSize()), queryWrapper);
    }

    default List<MallOrderEntity> selectListByQueryCondition(MallOrderQueryDTO orderQueryDTO) {
        QueryWrapper<MallOrderEntity> queryWrapper = new QueryWrapper<>();

        if (orderQueryDTO.getShopId() != null) {
            queryWrapper.eq("shop_id", orderQueryDTO.getShopId());
        }

        String orderNumber = StringUtils.trimToNull(orderQueryDTO.getOrderNumber());
        if (orderNumber != null) {
            queryWrapper.like("number", orderNumber);
        }

        Date fromDate = orderQueryDTO.getFromDate();
        if (fromDate != null) {
            queryWrapper.ge("create_time", fromDate);
        }

        Date toDate = orderQueryDTO.getToDate();
        if (toDate != null) {
            queryWrapper.lt("create_time", DateUtils.addDays(toDate, 1));
        }

        if (orderQueryDTO.getStatus() != null) {
            queryWrapper.eq("status", orderQueryDTO.getStatus());
        }

        if (orderQueryDTO.getRefundStatus() != null) {
            queryWrapper.eq("refund_status", orderQueryDTO.getRefundStatus());
        }

        Date hexiaoFromDate = orderQueryDTO.getHexiaoFromDate();
        if (hexiaoFromDate != null) {
            queryWrapper.ge("hexiao_time", hexiaoFromDate);
        }

        Date hexiaoToDate = orderQueryDTO.getHexiaoToDate();
        if (hexiaoToDate != null) {
            queryWrapper.lt("hexiao_time", DateUtils.addDays(hexiaoToDate, 1));
        }

        queryWrapper.eq("type", orderQueryDTO.getType());

        return selectList(queryWrapper);
    }

    default List<MallOrderEntity> selectPriceAndQuantityByShopIdAndFinished(Long shopId) {
        return selectList(new QueryWrapper<MallOrderEntity>()
                .select("price", "quantity")
                .eq("shop_id", shopId)
                .eq("status", MallOrderStatusEnum.FINISHED.getCode()));
    }

    default List<MallOrderEntity> selectListByStatus(List<Integer> statusList) {
        return selectList(new QueryWrapper<MallOrderEntity>()
                .in("status", statusList));
    }

    default List<MallOrderEntity> selectListByShopIdAndStatus(Long shopId, List<Integer> statusList) {
        return selectList(new QueryWrapper<MallOrderEntity>()
                .eq("shop_id", shopId)
                .in("status", statusList));
    }

    default Long selectShopIdByVirNumber(String virNumber) {
        MallOrderEntity mallOrderEntity = selectOne(new QueryWrapper<MallOrderEntity>()
                .select("shop_id")
                .eq("vir_number", virNumber)
                .last("limit 1"));
        if (mallOrderEntity != null) {
            return mallOrderEntity.getShopId();
        }
        return null;
    }

    default MallOrderEntity selectByVirNumber(String virNumber) {
        return selectOne(new QueryWrapper<MallOrderEntity>()
                .eq("vir_number", virNumber)
                .last("limit 1"));
    }

    default List<MallOrderEntity> selectListByUserIdAndStatus(Integer userId, Integer status) {
        QueryWrapper<MallOrderEntity> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("user_Id", userId);

        if (status != null) {
            queryWrapper.eq("status", status);
        }

        queryWrapper.orderByDesc("create_time");

        return selectList(queryWrapper);
    }

    default List<MallOrderEntity> selectRefundListByUserId(Integer userId) {
        return selectList(new QueryWrapper<MallOrderEntity>()
                .eq("user_Id", userId)
                .isNotNull("refund_status")
                .orderByDesc("application_time"));
    }

    default List<MallOrderEntity> selectNumberByUserId(Integer userId) {
        return selectList(new QueryWrapper<MallOrderEntity>()
                .select("id", "number")
                .eq("user_id", userId)
                .orderByDesc("create_time"));
    }

    default List<MallOrderEntity> selectListByUserIdAndKeyword(Integer userId, String keyword) {
        QueryWrapper<MallOrderEntity> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("user_id", userId);

        if (StringUtils.isNotBlank(keyword)) {
            queryWrapper.and(mallProductEntityQueryWrapper -> mallProductEntityQueryWrapper
                    .like("number", keyword)
                    .or()
                    .like("product_name", keyword));
        }

        queryWrapper.orderByDesc("create_time");

        return selectList(queryWrapper);
    }

    default MallOrderEntity selectByOrderNumber(String number) {
        return selectOne(new QueryWrapper<MallOrderEntity>()
                .eq("number", number)
                .last("limit 1"));
    }

    default MallOrderEntity selectOneByUserIdAndProductId(Integer userId, Long productId) {

        LimitedDurationDTO durationDto = LimitedDurationDTO.getDurationDto(new Date());
        return selectOne(new QueryWrapper<MallOrderEntity>()
                .select("id")
                .eq("user_id", userId)
                .eq("product_id", productId)
                .ne("status", MallOrderStatusEnum.CLOSED.getCode())
                .ge("create_time", durationDto.getStartDate())
                .lt("create_time", durationDto.getEndDate())
                .last("limit 1"));
    }

    default List<MallOrderEntity> selectListByUserIdAndProductIds(Integer userId, ArrayList<Long> productIds){

        Date date = new Date();
        return selectList(new QueryWrapper<MallOrderEntity>()
                .select("id")
                .eq("user_id", userId)
                .in("product_id", productIds)
                .ne("status", MallOrderStatusEnum.CLOSED.getCode())
                .ge("create_time", (DateUtil.beginOfMonth(date)))
                .lt("create_time", (DateUtil.endOfMonth(date)))
                .last("limit 1"));
    }

    default List<MallOrderEntity> selectToDayOrderByExchType(Integer exchangeType, Integer userId){

        Date date = new Date();
        return selectList( new QueryWrapper<MallOrderEntity>()
                .eq("user_id", userId)
                .eq("exchange_type", exchangeType)
                .ne("status", MallOrderStatusEnum.CLOSED.getCode())
                .ge("create_time", (DateUtil.beginOfDay(date)))
                .lt("create_time", (DateUtil.endOfDay(date)))
                .last("limit 1"));
    }

    default List<MallOrderEntity> selectThisWeekOrderByPid(Long productId, Integer userId){

        Date date = new Date();
        return selectList( new QueryWrapper<MallOrderEntity>()
                .eq("user_id", userId)
                .eq("product_id", productId)
                .ne("status", MallOrderStatusEnum.CLOSED.getCode())
                .ge("create_time", (DateUtil.beginOfWeek(date)))
                .lt("create_time", (DateUtil.endOfWeek(date)))
                .last("limit 1"));
    }
}
